package com.norman.sorry.core.tiles;

import java.awt.Color;
import java.util.Hashtable;
import java.util.Map;

/**
 * A helper class for creating a concrete version of a linked tile.
 * 
 * @author Brian Norman
 * @version 0.0.1 beta
 * @since 0.0.1 beta
 */
public abstract class AbstractLinkedTile extends AbstractTile implements ILinkedTile {

   /**
    * The tile that comes before this tile.
    */
   protected ILinkedTile             previous;

   /**
    * A map of what tile comes after this tile for each color.
    */
   protected Map<Color, ILinkedTile> nextMap;

   /**
    * The default tile that comes after this tile.
    */
   protected ILinkedTile             next;

   /**
    * Creates a new linked tile with the given properties.
    * 
    * @param start
    *           whether this tile is a starting tile.
    * @param safe
    *           whether this tile is part of a safe zone.
    * @param home
    *           whether this tile is a home tile.
    */
   public AbstractLinkedTile(boolean start, boolean safe, boolean home) {
      super(start, safe, home);

      previous = null;
      nextMap = new Hashtable<Color, ILinkedTile>();
      next = null;
   }

   /**
    * Sets the tile that comes before this tile.
    * 
    * @param previous
    *           the tile that comes before this tile.
    */
   public void setPrevious(ILinkedTile previous) {
      this.previous = previous;
   }

   /**
    * {@inheritDoc}
    * 
    * @see com.norman.sorry.core.tiles.ILinkedTile#getPrevious()
    */
   @Override
   public ILinkedTile getPrevious() {
      return previous;
   }

   /**
    * Sets the tile that comes after this tile for the given color.
    * 
    * @param color
    *           the switch color.
    * @param next
    *           the tile that comes after this tile.
    */
   public void setNext(Color color, ILinkedTile next) {
      if (color != null && next != null) {
         this.nextMap.put(color, next);
      } else {
         setNext(next);
      }
   }

   /**
    * Sets the default tile that comes after this tile.
    * 
    * @param next
    *           the default tile that comes after this tile.
    */
   public void setNext(ILinkedTile next) {
      this.next = next;
   }

   /**
    * {@inheritDoc}
    * 
    * @see com.norman.sorry.core.tiles.ILinkedTile#getNext(Color)
    */
   @Override
   public ILinkedTile getNext(Color color) {
      ILinkedTile next = null;
      if (color != null) {
         next = nextMap.get(color);
      }
      if (next == null) {
         next = this.next;
      }
      return next;
   }

}
